﻿#include <iostream>
#include <assert.h>

typedef long long LONG64;

// 9223372036854775807
#define MAX_POSITIVE_NUM 0x7fffffffffffffff
// -9223372036854775808
// -9000000000000000000
#define MAX_NEGATIVE_NUM (0x7fffffffffffffff + 1)

static void myAssert(bool res, const char* msg)
{
	assert(res && msg);
}

static LONG64 judgeValidNumber(const char* input)
{
	if (!input) myAssert(false, "input is nullptr");

	auto len = strlen(input);
	if (len == 0) myAssert(false, "size of input is 0");

	char cur;
	LONG64 curNum = 0i64;
	if (len == 1)
	{
		cur = input[0];
		if (cur < '0' || cur > '9') myAssert(false, "character exists");

		sscanf_s(input, "%lld", &curNum);
		return curNum;
	}

	bool isNegative = false;
	LONG64 navNum = 0i64;
	LONG64 mul10 = 0i64;
	char numStr[2] = { 0 };
	for (int i = 0; i < len; i++)
	{
		cur = input[i];
		if (i == 0)
		{
			if (cur != '-' && (cur <= '0' || cur > '9'))
				myAssert(false, "character exists or first is zero");

			if (cur == '-')
			{
				isNegative = true;
			}
		}

		if (i > 0)
		{
			if (isNegative && i == 1 && cur == '0')
			{
				myAssert(false, "first is zero");
			}

			if (cur < '0' || cur > '9')
			{
				myAssert(false, "character exists");
			}
		}

		if ((i == 0 && !isNegative) || i > 0)
		{
			numStr[0] = cur;
			sscanf_s(numStr, "%lld", &curNum);
			curNum = -curNum;
			if (navNum == MAX_NEGATIVE_NUM / 10)
			{
				myAssert(curNum >= MAX_NEGATIVE_NUM % 10, "overflow exception");
			}
			else if (navNum < MAX_NEGATIVE_NUM / 10)
			{
				myAssert(false, "overflow exception");
			}

			navNum = navNum * 10 + curNum;
		}
	}

	if (!isNegative && navNum == MAX_NEGATIVE_NUM)
		myAssert(false, "overflow exception");

	navNum = isNegative ? navNum : -navNum;
	return navNum;
}

/**
 * 给定一个字符串，如果该字符串符合人们日常书写一个整数的形式，返回int类型的这个数；
 * 如果不符合或者越界返回-1或者报错。
 */
int main_WriteAStringIsInteger()
{
#define MAX_STR_LEN 100
	char testNumberText[][MAX_STR_LEN] = {
		"0",
		//"-0",
		//"-1",
		"12",
		//"01",
		"56435",
		"9223372036854775807",
		//"9223372036854775808",
		"-9223372036854775808",
		//"9223372036854775809",
		"-9223372036854775807",
		//"9223372036854775810",
		"922337203685477580",
		//"92233720368547758100",
	};

	auto size = sizeof(testNumberText) / MAX_STR_LEN;
	for (int i = 0; i < size; i++)
	{
		auto res = judgeValidNumber(testNumberText[i]);
		printf("text[%d]:\"%s\"=> %lld\n", i, testNumberText[i], res);
	}

	return 0;
}